<template>
  <el-card class="mt-20" shadow="hover">
    <el-form>
      <el-form-item label="属性名">
        <el-input
          placeholder="请输入属性名"
          class="AddOrUpdateAttr__fromInput"
          v-model="attrFormData.attrName"
        />
      </el-form-item>
      <!-- 添加按钮的禁用功能：attrName有值不禁用disabled：false，attrName没值禁用disabled：true -->
      <el-form-item>
        <el-button
          type="primary"
          :disabled="!attrFormData.attrName"
          @click="addAttrValue"
          >添加属性值</el-button
        >
        <el-button default @click="cancel">取消</el-button>
        <el-table :data="attrFormData.attrValueList" class="mt-20">
          <el-table-column
            label="序号"
            type="index"
            width="80"
            align="center"
          ></el-table-column>
          <!-- 
            点击添加，给数组添加一个对象 
            给input添加ref，让聚焦
            收集表单的数据
            编辑和显示状态的切换
            给对象添加标识 true是编辑模式 
            input失去焦点切换显示模式 
            点击div切换编辑模式
            回车切换显示模式
        
            场景1，添加内容为空时，删除整条数据
            场景2，添加内容重复时，不可以添加
            问题3，添加多条后，在切换编辑模式时 只有最后一个input有聚焦效果
              原因， 给添加的聚焦效果绑定的是一个input实例，每次用v-show的实例对象只是隐藏，节点是还存在，所以是用的同一个实例对象，会有覆盖效果
              解决，用v-if 因为v-if节点会被删除掉，每次都是创建新的input实例，确保每一个对象用的实例对象不同
           -->
          <el-table-column label="属性值名称">
            <template v-slot="{ row, $index }">
              <el-input
                placeholder="请输入属性值名称"
                size="small"
                class="AddOrUpdateAttr__tableInput"
                v-model="row.valueName"
                ref="inputRef"
                v-if="row.isShow"
                @blur="switchShow(row, $index)"
                @keyup.enter="switchShow(row, $index)"
              />
              <div v-else @click="switchEdit(row)">
                {{ row.valueName }}
              </div>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template v-slot="{ row, $index }">
              <el-popconfirm
                :title="`你确定要删除 ${row.valueName}  属性值吗?`"
                @confirm="delAttrValue($index)"
              >
                <template #reference>
                  <el-button
                    :icon="Delete"
                    size="small"
                    type="danger"
                    title="删除"
                  ></el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item class="mt-20">
        <!-- 
          确定按钮的禁用功能 disabled：true 禁用
            1.必须要有属性名
            2.至少要有属性值，并且属性值名称不可以为空
            满足1,2 才不禁用
         -->
        <el-button type="primary" :disabled="isDisabled" @click="submit"
          >保存</el-button
        >
        <el-button default @click="cancel">关闭</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script lang="ts">
export default {
  name: "AddOrUpdateAttr",
};
</script>

<script lang="ts" setup>
import { Delete } from "@element-plus/icons-vue";
import { AttrItem, AttrValueItem } from "@/api/product/model/attrModel";
import { ElMessage } from "element-plus";
import { ref, reactive, nextTick, computed } from "vue";
import { addOrUpdateAttrApi } from "@/api/product/attr";
import { useCategoryStore } from "@/stores/category";
import { useAttrStore } from "@/stores/attr";
const categoryStore = useCategoryStore();
const attrStore = useAttrStore();

// 提交按钮
const submit = async () => {
  // 如果有id 那么修改
  if (attrStore.attr.id) {
    await addOrUpdateAttrApi({
      ...attrFormData,
      categoryId: categoryStore.category3Id as number, //三级id
      categoryLevel: 3,
      id: attrStore.attr.id as number,
    });
    ElMessage.success("修改属性成功~");
  } else {
    await addOrUpdateAttrApi({
      ...attrFormData,
      categoryId: categoryStore.category3Id as number, //三级id
      categoryLevel: 3,
    });
    ElMessage.success("添加属性成功~");
  }
  cancel();
};
// 确定按钮的禁用
const isDisabled = computed(() => {
  return (
    !attrFormData.attrName ||
    !attrFormData.attrValueList.some((attrValue) => attrValue.valueName)
  );
});
// 定义表单数据
const attrFormData = reactive<AttrItem>({
  attrName: attrStore.attr.attrName,
  attrValueList: attrStore.attr.attrValueList,
});
const inputRef = ref();
// 点击添加属性值
const addAttrValue = () => {
  // 1.给attrValueList数组添加一个对象
  attrFormData.attrValueList.push({
    // 给每一个对象添加一个标识，用于切换input和文本状态（编辑和显示状态）
    isShow: true,
    valueName: "",
  });
  // 2.在更新页面后获取input实例，让input聚焦
  nextTick(() => {
    inputRef.value.focus();
  });
};
// 失去焦点/回车切换显示模式
const switchShow = (row: AttrValueItem, index: number) => {
  // 如果输入内容为空，删除整条数据(通过下标剪切)
  if (!row.valueName) {
    attrFormData.attrValueList.splice(index, 1);
    return;
  }
  // 如果输入内容重复，不添加数据
  const isRepeat = attrFormData.attrValueList.some((attrValue) => {
    // some 找到返回true
    if (attrValue === row) return false; // 找到自己
    if (attrValue.valueName === row.valueName) return true;
    return false;
  });
  if (isRepeat) {
    ElMessage.error("请不要输入相同的属性值！");
    return;
  }

  // 内容不为空切换到显示模式
  row.isShow = false;
};
// 删除属性值
const delAttrValue = (index: number) => {
  attrFormData.attrValueList.splice(index, 1);
};
// 点击div切换编辑模式
const switchEdit = async (row: AttrValueItem) => {
  row.isShow = true;
  // 注意，原来使用v-show,节点是隐藏，还存在，所以可以直接使用节点
  // 现在用v-if ，每次都是新的节点，更新页面是异步的，要确保有节点（页面更新）才可以操作
  // nextTick的第二种用法
  await nextTick();
  inputRef.value.focus();
};

// 自定义事件，点击关闭按钮让父组件切换显示属性列表
const emit = defineEmits(["setIsShowAttrList"]);
const cancel = () => {
  emit("setIsShowAttrList", true);
};
</script>

<style scoped>
.AddOrUpdateAttr__fromInput {
  width: 200px;
}
.tooltip-base-box .box-item {
  width: 110px;
  margin-top: 10px;
}
</style>
